package com.foogui.utils;

import cn.hutool.core.lang.UUID;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Component
public class SimpleRedisLock implements ILock{

    public static final String uuid= UUID.randomUUID().toString(true)+"-";


    //定义锁的前缀
    public static final String LOCK_KEY_PREFIX="lock:";

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 获取锁，redis中key含锁名，value为uuid+线程id，避免分布式环境下不同线程出现id相同情况
     * @param duration 锁最长持有时间，过期自动释放，避免占内存
     * @param lockName
     * @return
     */
    @Override
    public synchronized boolean tryLock(String lockName,Long duration, TimeUnit timeUnit) {
        long id = Thread.currentThread().getId();
        Boolean res = stringRedisTemplate.opsForValue().setIfAbsent(LOCK_KEY_PREFIX + lockName, uuid+id, duration, timeUnit);
        //避免res为空出现拆箱空指针的问题
        return Boolean.TRUE.equals(res);
    }

    /**
     * 线程只能释放自己的锁，不能释放他人的
     * @param name
     */
    @Override
    public synchronized void unlock(String name) {
        long id = Thread.currentThread().getId();
        String threadId=uuid+id;
        String value = stringRedisTemplate.opsForValue().get(LOCK_KEY_PREFIX + name);
        //判断是否是当前线程持有锁
        //可以写到lua脚本中
        if (threadId.equals(value)){
            stringRedisTemplate.delete(LOCK_KEY_PREFIX + name);
        }

    }
}
